如何基于 ZEGO SDK 实现 Flutter 一对一音视频聊天应用

您所在的位置:网站首页 flutter platformview原理 如何基于 ZEGO SDK 实现 Flutter 一对一音视频聊天应用

如何基于 ZEGO SDK 实现 Flutter 一对一音视频聊天应用

2023-03-25 02:36| 来源: 网络整理| 查看: 265

之前的文章发布了ZEGO SDK实现Android端音视频通话应用的开发教程,不少开发者反馈很实用,能不能也出一版Flutter的教程。

有求必应,这不小编来了~

我们封装了ZEGO Flutter SDK,本文将引导你如何使用ZEGO Flutter SDK 快速轻松的构建一个跨平台音视频聊天应用,减少开发成本。

1 准备环境

在开始集成 ZEGO Express SDK 前,请确保开发环境满足以下要求:

Flutter 1.12 或以上版本。iOS 7.0 或以上版本,且支持音视频的 iOS 设备或模拟器(推荐使用真机)。Android4.4 或以上版本,且支持音视频的 Android 设备或模拟器(推荐使用真机)。如果为真机,请开启“允许调试”选项。iOS / Android 设备已经连接到 Internet。

请配置开发环境如下:

Android Studio:“Preferences > Plugins”,搜索 “Flutter”插件进行下载,并在插件中配置已经下载好的 Flutter 的 SDK 路径。VS Code: 在应用商店中搜索 “Flutter”扩展并下载。

以上任一开发环境配置好 Flutter 环境后,在终端执行 flutter doctor,根据提示内容补全相关未下载的依赖项。

2 项目准备 2.1 创建项目

进入 即构官网,在创建项目,【ZEGO控制台】.并申请有效的 AppID,这一步很关键,appid为应用的唯一标识,如身份证号,是应用的身份证明,用于明确你的项目及组织身份。zego提供的服务也是基于APP ID;

App ID的获取方式很简单,只需3~5分钟,在即构官网-我的项目-创建即可。创建的项目信息可用于SDK的集成和配置;

2.2 Token 鉴权

登录房间时必须 使用Token 鉴权 ,可参考 Token 鉴权 教程 。 为了方便开发阶段的调试,开发者可直接在 ZEGO 控制台获取临时 Token(有效期为 24 小时) 来使用,详情请参考 控制台(新版) - 项目管理 中的 “项目信息”。.

3 集成 3.1 项目设置

开始集成前,请参考 Flutter 文档 - Get Started.创建一个 Flutter 项目。 如已有项目,本步骤可忽略;

接下来我们需要对项目做一下简单的配置,便于导入和使用ZEGO Flutter SDK。

3.2 导入 SDK

打开 “pubspec.yaml” 文件,添加 “zego_express_engine” 依赖,有以下两种形式:

以 “pub” 形式依赖(推荐):dependencies: flutter: sdk: flutter zego_express_engine: ^2.0.0 以 “git” 形式依赖:dependencies: flutter: sdk: flutter zego_express_engine: git: url: git://github.com/zegoim/zego-express-flutter-sdk.git ref: master

2.添加完成并保存文件后,在终端执行 flutter pub get。

4 设置权限

以上步骤集成已完成,为保证SDK运行效果更佳,需要在应用中根据实际应用需要,设置应用所需权限。步骤如下:

4.1 Android 添加权限

进入 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限。

因为 Android 6.0 在一些比较重要的权限上要求必须申请动态权限,不能只通过 “AndroidMainfest.xml” 文件申请静态权限。请在 Android 原生层参考执行如下代码,其中 “requestPermissions” 是 “Activity” 的方法。

String[] permissionNeeded = { "android.permission.CAMERA", "android.permission.RECORD_AUDIO"}; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, "android.permission.CAMERA") != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, "android.permission.RECORD_AUDIO") != PackageManager.PERMISSION_GRANTED) { requestPermissions(permissionNeeded, 101); } }

具体的权限说明如下:

在这里插入图片描述

4.2 iOS 添加权限

打开项目,选择菜单 “TARGETS > Info > Custom iOS Target Properties”。

在这里插入图片描述

单击 “+” 按钮,添加摄像头和麦克风权限。

Privacy - Camera Usage DescriptionPrivacy - Microphone Usage Description

权限添加完成后,如图所示:

在这里插入图片描述

5 实现流程

如以下流程图,用户A与B通过 ZEGO Express SDK 进行视频通话,以用户 A 拉取用户 B 的流为例:

在这里插入图片描述

为保证实时音视频的通话质量,推拉流关键流程需按照API的正确调用时序进行,完整时序如下图:

在这里插入图片描述

5.1 创建引擎

1. 引入 SDK

在项目中引入 SDK。

1import 'package:zego_express_engine/zego_express_engine.dart';

2. 创建引擎

调用 createEngineWithProfile 接口,将申请到的 AppID 传入参数 “appID”。

ZegoEngineProfile profile = ZegoEngineProfile( appID, // 请通过官网注册获取,格式为:1234567890 ZegoScenario.General, // 通用场景接入 enablePlatformView: true); // 创建引擎 ZegoExpressEngine.createEngineWithProfile(profile); 5.2 登录房间

1. 登录

传入用户 ID 参数 “userID” 创建 ZegoUser 用户对象后,调用 loginRoom 接口,传入房间 ID 参数 “roomID” 和用户参数 “user”,登录房间。

同一个 AppID 内,需保证 “roomID” 信息的全局唯一。同一个 AppID 内,需保证 “userID”全局唯一,建议开发者将其设置成一个有意义的值,可将 “userID” 与自己业务账号系统进行关联。“ZegoUser” 的构造方法ZegoUser.id 会将 “userName” 设为与传的参数 “userID” 一样。“userID” 与 “userName”不能为 “null”,否则会导致登录房间失败。// 创建用户对象 ZegoUser user = ZegoUser.id('user1'); // 只有传入 “isUserStatusNotify” 参数取值为 “true” 的 ZegoRoomConfig,才能收到 onRoomUserUpdate 回调。 ZegoRoomConfig config = ZegoRoomConfig.defaultConfig(); config.isUserStatusNotify = true; // token 由用户自己的服务端生成,为了更快跑通流程,也可以通过即构控制台获取临时的音视频 token config.token = "xxxx"; // 开始登录房间 ZegoExpressEngine.instance.loginRoom('room1', user, config: config);

2. 监听登录房间后的事件回调 根据实际应用需要,在登录房间后监听想要关注的事件通知,比如房间状态更新、用户状态更新、流状态更新等。

onRoomStateUpdate:房间状态更新回调。登录房间后,当房间连接状态发生变更(如出现房间断开,登录认证失败等情况),SDK会通过该回调通知。 onRoomUserUpdate:用户状态更新回调。登录房间后,当房间内有用户新增或删除时,SDK 会通过该回调通知。只有调用 loginRoom 接口登录房间时传入 ZegoRoomConfig 配置,且 “isUserStatusNotify”参数取值为 “true” 时,用户才能收到 onRoomUserUpdate 回调。onRoomStreamUpdate:流状态更新回调。登录房间后,当房间内有用户新推送或删除音视频流时,SDK 会通过该回调通知。// 以下为常用的房间相关回调 // 房间状态更新回调 ZegoExpressEngine.onRoomStateUpdate = (String roomID, ZegoRoomState state, int errorCode, Map extendedData) { // 根据需要实现事件回调 }; // 用户状态更新 ZegoExpressEngine.onRoomUserUpdate = (String roomID, ZegoUpdateType updateType, List userList) { // 根据需要实现事件回调 }; // 流状态更新 ZegoExpressEngine.onRoomStreamUpdate = (String roomID, ZegoUpdateType updateType, List streamList) { // 根据需要实现事件回调 }; 5.3 推流

1. 开始推流 调用 startPublishingStream 接口,传入流 ID 参数 “streamID”,向远端用户发送本端的音视频流。 同一个 AppID 内,需保证 “streamID” 全局唯一。如果同一个 AppID 内,不同用户各推了一条 “streamID” 相同的流,会导致后推流的用户推流失败。

// 开始推流 ZegoExpressEngine.instance.startPublishingStream("streamID");

2. 启用本地渲染和预览 如果希望看到本端的画面,可将画面渲染后,调用 startPreview 接口启动本地预览。 Flutter 的渲染方式有两种:PlatformView 与 TextureRenderer。与 TextureRenderer 相比,PlatformView占用资源稍高,且稳定性偏低,但随着 Flutter 版本迭代,鲁棒性不断提高。开发者可根据实际情况通过任意一种方式实现渲染。

使用 TextureRenderer 方式渲染

开启 TextureRenderer 后,在销毁引擎之前,只能使用 TextureRenderer 而不能使用 PlatformView。 (1)创建预览用的 “TextureRenderer”(外接纹理)。

void createPreviewRenderer() { ZegoExpressEngine.instance.createTextureRenderer(widget.screenWidthPx, widget.screenHeightPx).then((textureID) { _previewViewID = textureID; setState(() { // Create a Texture Widget Widget previewViewWidget = Texture(textureId: textureID); // 将此 Widget 加入到页面的渲染树中以显示预览画面 _previewViewWidget = previewViewWidget; }); // Start preview using texture renderer _startPreview(textureID); }); }

(2)使用 TextureRenderer 的 “textureID” 作为 “viewID” 创建一个 ZegoCanvas 对象,开始预览。 void _startPreview(int viewID) {

// Set the preview canvas ZegoCanvas previewCanvas = ZegoCanvas.view(viewID); // Start preview ZegoExpressEngine.instance.startPreview(canvas: previewCanvas); }

3. 监听推流后的事件回调

根据实际应用需要,在推流后监听想要关注的事件通知,比如推流状态更新等。 onPublisherStateUpdate:推流状态更新回调。调用推流接口成功后,当推流状态发生变更(如出现网络中断导致推流异常等情况),SDK 在重试推流的同时,会通过该回调通知。

// 常用的推流相关回调 // 推流状态更新回调 ZegoExpressEngine.onPublisherStateUpdate = (String streamID, ZegoPublisherState state, int errorCode, Map extendedData) { // 根据需要实现事件回调 }; 5.4 拉流

调用 startPlayingStream 接口,根据传入的流 ID 参数 “streamID”,拉取远端推送的音视频流,并根据需要渲染拉流画面。

若仅需拉音频流,不需要显示拉流画面,可直接调用 startPlayingStream 接口。 ZegoExpressEngine.instance.startPlayingStream(streamID);若需要在拉流的同时,渲染拉流画面,Flutter 的渲染方式有两种:PlatformView 与 TextureRenderer。与 TextureRenderer 相比,PlatformView占用资源稍高,且稳定性偏低,但随着 Flutter 版本迭代,鲁棒性不断提高。开发者可根据实际情况通过任意一种方式实现渲染。

使用 TextureRenderer 方式渲染 (1)创建预览用的 “TextureRenderer”(外接纹理)。

ZegoExpressEngine.instance.createTextureRenderer(width.toInt(), height.toInt()).then((viewID) { _playViewID = viewID; // 将得到的 Widget 加入到页面的渲染树中以显示拉流画面 setState(() => _playViewWidget = Texture(textureId: viewID)); _startPlayingStream(viewID, streamID); });

(2)使用 TextureRenderer 的 “textureID” 作为 “viewID” 创建一个 ZegoCanvas 对象,开始拉流并渲染拉流画面。

void _startPlayingStream(int viewID, String streamID) { ZegoCanvas canvas = ZegoCanvas.view(viewID); ZegoExpressEngine.instance.startPlayingStream(streamID, canvas: canvas); } 5.5 体验实时音视频功能

在真机中运行项目,运行成功后,可以看到本端视频画面。 为方便体验,ZEGO 提供了一个 Web 端调试示例,在该页面下,输入相同的 AppID、RoomID、Server 地址和 Token,即可加入同一房间与真机设备互通。当成功开始音视频通话时,可以听到远端的音频,看到远端的视频画面。

5.6 停止推拉流

1. 停止推流/预览/渲染 调用 stopPublishingStream 接口停止向远端用户发送本端的音视频流。

// 停止推流 ZegoExpressEngine.instance.stopPublishingStream();

如果启用了本地预览,调用 stopPreview 接口停止预览。

// 停止预览 ZegoExpressEngine.instance.stopPreview();

如果预览时创建了 TextureRenderer,需要调用 destroyTextureRenderer 接口销毁 TextureRenderer。

// _previewViewID 为调用 createTextureRenderer 时得到的 viewID ZegoExpressEngine.instance.destroyTextureRenderer(_previewViewID);

如果预览时创建了 PlatformView,需要调用 destroyPlatformView 接口销毁 PlatformView。

// _previewViewID 为调用 [createPlatformView] 时得到的 viewID ZegoExpressEngine.instance.destroyPlatformView(_previewViewID);

2. 停止拉流/渲染

调用 stopPlayingStream 接口停止拉取远端推送的音视频流。

// 停止拉流 ZegoExpressEngine.instance.stopPlayingStream(streamID, canvas: _playCanvas);

如果拉流时创建了 TextureRenderer,需要调用 destroyTextureRenderer 接口销毁 TextureRenderer。

// _playViewID 为调用 [createTextureRenderer] 时得到的 viewID ZegoExpressEngine.instance.destroyTextureRenderer(_playViewID);

如果拉流时创建了 PlatformView,需要调用 destroyPlatformView 接口销毁 PlatformView。

// _playViewID 为调用 [createPlatformView] 时得到的 viewID ZegoExpressEngine.instance.destroyPlatformView(_playViewID); 5.7 退出房间

调用 logoutRoom 接口退出房间。

// 退出房间 ZegoExpressEngine.instance.logoutRoom('room1'); 5.8 销毁引擎

调用 destroyEngine 接口销毁引擎,用于释放 SDK 使用的资源。

// 销毁引擎 ZegoExpressEngine.destroyEngine(); 结尾

恭喜,你已经通过ZEGO Flutter SDK完成了自己的实时音视频通话应用,Flutter为应用开发带来了革新,带着学习交流的态度,希望对于想要学习应用Flutter的同学有所帮助。

获取Demo

获取本文的Demo、开发文档、技术支持。 获取SDK的商务活动、热门产品。注册即构ZEGO开发者帐号,快速开始。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3